package com.jiang.server;

import com.jiang.Domain.Message;
import com.jiang.Domain.MessageType;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Jiang
 * @version 1.0
 * @date 2023/11/29 13:34
 * 和客户端通信
 */
public class ServerConnectClientThread implements Runnable {
    private Socket socket;
    private String userId;// 连接服务端的用户id


    public ServerConnectClientThread(Socket socket, String userId) {
        this.socket = socket;
        this.userId = userId;
    }

    public Socket getSocket() {
        return socket;
    }

    @Override
    public void run() {
        while (true) {
            try {
                System.out.println("服务端和客户端保持通信" + userId);
                ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
                Message message = (Message) objectInputStream.readObject();
                if (MessageType.MESSAGE_GET_ONLINE_FRIEND.equals(message.getMesType())) {
                    System.out.println(message.getSender() + " 要在线用户列表");
                    String onlineUser = ManageServerConnectClientThread.getOnlineUser();
                    // 构建Message对象，返回给客户端
                    Message message2 = new Message();
                    message2.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
                    message2.setContent(onlineUser);
                    message2.setGetter(message.getSender());
                    // 返回客户端
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
                    objectOutputStream.writeObject(message2);
                } else if (MessageType.MESSAGE_CLIENT_EXIT.equals(message.getMesType())) {
                    System.out.println(message.getSender() + " 退出系统");
                    Thread.sleep(1000); // 客户端发数据给服务端，导致socket关闭，客户端的socket就一直报错，所以这里要慢点关
                    // 将这个客户端对应的线程从集合中删除
                    ManageServerConnectClientThread.removeServerConnectClientThread(message.getSender());
                    socket.close();
                    break; // 该线程也要结束了
                } else if (MessageType.MESSAGE_COMM_MES.equals(message.getMesType())) {
                    System.out.println(message.getSender() + "和" + message.getGetter() + "通信");
                    // 得到getterId的socket线程
                    ServerConnectClientThread serverConnectClientThread = ManageServerConnectClientThread.getServerConnectClientThread(message.getGetter());
                    // 然后得到对应socket输出流，将message转发给指定的客户端
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(serverConnectClientThread.socket.getOutputStream());
                    objectOutputStream.writeObject(message); // 如果客户不在线，则可以保存到数据库，这样就可以离线留言
                } else if (MessageType.MESSAGE_TO_ALL_MES.equals(message.getMesType())) {
                    System.out.println(message.getSender() + "和所有人通信");
                    // 遍历 管理线程的集合 得到所以线程的socket， 然后发送message
                    HashMap<String, ServerConnectClientThread> hm = ManageServerConnectClientThread.getHm();
                    for (Map.Entry<String, ServerConnectClientThread> entry : hm.entrySet()) {
                        // 排除群发消息的用户
                        if (!entry.getKey().equals(message.getSender())) {
                            ObjectOutputStream objectOutputStream = new ObjectOutputStream(entry.getValue().socket.getOutputStream());
                            objectOutputStream.writeObject(message);
                        }
                    }
                } else if (MessageType.MESSAGE_FILE_MES.equals(message.getMesType())) {
                    System.out.println(message.getSender() + "给" + message.getGetter() + "发送文件");
                    // 根据 getterId 获取对应的线程，将message对象转发
                    ObjectOutputStream objectOutputStream = new ObjectOutputStream(ManageServerConnectClientThread.getServerConnectClientThread(message.getGetter()).socket.getOutputStream());
                    objectOutputStream.writeObject(message);
                }
                else {
                    System.out.println("其它type");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
